package uk.ac.glasgow.demosocs.electoratestore;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * Concrete implementation of electorate store 
 * @author Team K
 */
public class ElectorateStoreImpl implements ElectorateStore {
		private Map<String,HashSet<String>> electorates;
		private File storeFile;
		
		/**
		 * Constructs a new store in the specified file location.
		 * @param fileName
		 */
		public ElectorateStoreImpl(String fileName){
			storeFile = new File(fileName);
			if (storeFile.exists()){
				try {
					ObjectInputStream ois = 
						new ObjectInputStream(new FileInputStream(storeFile));
					electorates = (Map<String,HashSet<String>>) ois.readObject();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
			else
				this.electorates = new HashMap<String,HashSet<String>>();
		}
		
		/**
		 * Adds a new electorate to storage
		 * @param electorateID the ID of the particular electorate
		 * @param users a hash set of strings identifying the users
		 */
		public void addElectorate(String electorateID, HashSet<String> users) {
			electorates.put(electorateID, users);
			try {
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(storeFile));
				oos.writeObject(electorates);
				oos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/**
		 * Adds a new electorate to the storage
		 * @param electorateID the id of the particualr electorate
		 */
		public void addElectorate(String electorateID) {
			electorates.put(electorateID, new HashSet<String>());
			try {
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(storeFile));
				oos.writeObject(electorates);
				oos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/**
		 * Adds a user to an electorate grouping
		 * @param electorateID the electorate ID
		 * @param userID the user's ID
		 */
		public void addUserToElectorate(String electorateID, String userID) {
			HashSet<String> users = electorates.get(electorateID);
			if(users != null) users.add(userID);			
			try {
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(storeFile));
				oos.writeObject(electorates);
				oos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * Removes a user from an electorate grouping
		 * @param electorateID the electorate ID
		 * @param userID the user's ID
		 */
		public void removeUserFromElectorate(String electorateID, String userID) {
			HashSet<String> users = electorates.get(electorateID);
			if(users != null) users.remove(userID);			
			try {
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(storeFile));
				oos.writeObject(electorates);
				oos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/**
		 * Gets if a particular user is eligible to vote for a particular electorate
		 * @param electorateID the electorate ID
		 * @param userID the user's ID
		 * @return true/false as to wether the user can vote in that electorate grouping
		 */
		public boolean isEligible(String electorateID, String userID) {
			if(!electorates.containsKey(electorateID)) return false;
			return electorates.get(electorateID).contains(userID);
		}
	}

